Playbook 模板库
本篇收集运维中最常写的 Playbook 片段,每段都能独立运行。复制后改掉主机组、包名、路径等参数即可使用。片段均按 ansible-core 2.16/2.17 语法编写,模块名使用 FQCN。
安装并启动服务
最常见的「装包 + 启动 + 开机自启」三步,包管理用 ansible.builtin.package 自动适配发行版后端。
- name: 安装并启动 nginx
hosts: web
become: true
tasks:
- name: 安装 nginx
ansible.builtin.package:
name: nginx
state: present
- name: 启动并设置开机自启
ansible.builtin.service:
name: nginx
state: started
enabled: true
渲染配置并变更时重启
配置文件交给模板管理,只有内容真的变化时才通过 handler 重启服务,避免每次空转。
- name: 配置 nginx
hosts: web
become: true
tasks:
- name: 渲染主配置文件
ansible.builtin.template:
src: templates/nginx.conf.j2
dest: /etc/nginx/nginx.conf
mode: '0644'
backup: true
notify: 重启 nginx
handlers:
- name: 重启 nginx
ansible.builtin.service:
name: nginx
state: restarted
多个任务 notify 同一个 handler,整个 play 结束时 handler 也只执行一次。handler 在 tasks 全部跑完后才执行,中途失败的主机不会触发。
创建用户并配置 sudo
新建部署账号,同时把授权规则写成 /etc/sudoers.d/ 下的独立片段,并用 visudo 校验防止写坏 sudo 配置。
- name: 创建部署用户并授权 sudo
hosts: all
become: true
tasks:
- name: 创建 deploy 用户
ansible.builtin.user:
name: deploy
shell: /bin/bash
groups: wheel # Debian/Ubuntu 系改为 sudo
append: true
- name: 配置 sudo 免密片段
ansible.builtin.copy:
content: "deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart myapp\n"
dest: /etc/sudoers.d/deploy
mode: '0440'
validate: /usr/sbin/visudo -cf %s
拉取 git 仓库指定版本
把应用代码以固定 tag 检出到目标目录,保证多台机器版本一致。
- name: 拉取应用代码
hosts: app
become: true
tasks:
- name: 检出指定 tag
ansible.builtin.git:
repo: https://github.com/example/myapp.git
dest: /opt/myapp
version: v1.4.2 # 支持 branch、tag、commit hash
force: true # 本地有改动也强制覆盖
下载文件并校验 checksum
下载安装包/二进制时带上 SHA256 校验,防止传输损坏或来源被替换。
- name: 下载并校验安装包
hosts: all
become: true
tasks:
- name: 下载二进制并校验 SHA256
ansible.builtin.get_url:
url: https://example.com/releases/app-1.4.2.tar.gz
dest: /opt/downloads/app-1.4.2.tar.gz
checksum: sha256:6f2e9d0c1b8a... # 换成发布方提供的实际值
mode: '0644'
按发行版分支装不同包名
同一个软件在 Debian 系叫 apache2、RHEL 系叫 httpd,用 ansible_facts['os_family'] 分支处理。
- name: 安装 Apache(包名随发行版区分)
hosts: all
become: true
tasks:
- name: Debian 系安装 apache2
ansible.builtin.apt:
name: apache2
state: present
update_cache: true
when: ansible_facts['os_family'] == 'Debian'
- name: RHEL 系安装 httpd
ansible.builtin.dnf:
name: httpd
state: present
when: ansible_facts['os_family'] == 'RedHat'
批量创建目录与权限
一次声明多个目录及其属主、权限,比写多条 file 任务清爽。
- name: 准备应用目录
hosts: app
become: true
tasks:
- name: 批量创建目录
ansible.builtin.file:
path: "{{ item.path }}"
state: directory
owner: deploy
group: deploy
mode: "{{ item.mode }}"
loop:
- { path: /opt/myapp, mode: '0755' }
- { path: /opt/myapp/logs, mode: '0750' }
- { path: /var/lib/myapp, mode: '0750' }
滚动更新骨架
用 serial 控制每批更新的台数,pre_tasks 摘流量、post_tasks 做验证并接回,一批失败后续批次自动停止。
- name: 滚动更新应用
hosts: web
serial: 1 # 每批 1 台;也可写 '30%' 按比例
become: true
pre_tasks:
- name: 从负载均衡摘除本机(换成实际的 LB 操作)
ansible.builtin.command: /usr/local/bin/lb-drain {{ inventory_hostname }}
changed_when: false
tasks:
- name: 部署新版本
ansible.builtin.package:
name: myapp
state: latest
- name: 重启应用
ansible.builtin.service:
name: myapp
state: restarted
post_tasks:
- name: 等待服务端口就绪
ansible.builtin.wait_for:
port: 8080
timeout: 30
- name: 健康检查通过后接回负载均衡
ansible.builtin.command: /usr/local/bin/lb-join {{ inventory_hostname }}
changed_when: false
注册变量并按结果分支
把命令结果存进变量,后续任务根据返回码或输出决定走哪条分支。
- name: 检查并拉起服务
hosts: web
become: true
tasks:
- name: 查询 nginx 运行状态(失败不中断)
ansible.builtin.command: systemctl is-active nginx
register: nginx_status
ignore_errors: true
changed_when: false
- name: 未运行时启动 nginx
ansible.builtin.service:
name: nginx
state: started
when: nginx_status.rc != 0
查询类命令不改系统状态,但 command/shell 默认会报 changed。加 changed_when: false 让执行结果保持绿色,避免误报变更。
Vault 加密变量的定义与引用
敏感值(密码、密钥)用 ansible-vault 加密成文件,playbook 里按普通变量引用,运行时凭 vault 密码解密。
# 创建加密变量文件(交互输入 vault 密码)
ansible-vault create group_vars/all/vault.yml
# 文件内容示例:
# vault_db_password: S3cret!
- name: 配置数据库连接
hosts: db
become: true
vars_files:
- group_vars/all/vault.yml
tasks:
- name: 写入应用环境配置(模板内引用 vault 变量)
ansible.builtin.template:
src: app.env.j2 # 模板里写 DB_PASSWORD={{ vault_db_password }}
dest: /etc/myapp/app.env
mode: '0600'
运行时提供 vault 密码:
ansible-playbook --ask-vault-pass site.yml